package org.base23.video.service.impl;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.base23.video.domain.dto.DetailedPostureAnalysis;
import org.base23.video.domain.dto.SmartVideoPlayerDTO;
import org.base23.video.domain.dto.VideoAnalysisResult;
import org.base23.video.domain.dto.VideoInfo;
import org.base23.video.domain.entity.SmartVideoPlayer;
import org.base23.video.repository.SmartVideoPlayerRepository;
import org.base23.video.service.SmartVideoPlayerService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 智能视频播放器服务实现
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class SmartVideoPlayerServiceImpl implements SmartVideoPlayerService {

    private final SmartVideoPlayerRepository repository;
    private final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    @Transactional
    public Long generatePlayerInfo(Long userId, String resultId, String videoUrl, 
                                 VideoAnalysisResult.VideoAnalysisData analysisData,
                                 DetailedPostureAnalysis detailedAnalysis) {
        log.info("开始生成智能播放器信息，用户ID: {}, 结果ID: {}", userId, resultId);

        try {
            // 检查是否已存在
            SmartVideoPlayer existing = repository.findByUserIdAndResultId(userId, resultId);
            if (existing != null) {
                log.info("播放器信息已存在，更新现有记录，ID: {}", existing.getId());
                updateExistingPlayer(existing, videoUrl, analysisData, detailedAnalysis);
                return existing.getId();
            }

            // 创建新的播放器信息
            SmartVideoPlayer player = createNewPlayer(userId, resultId, videoUrl, analysisData, detailedAnalysis);
            repository.insert(player);
            
            log.info("智能播放器信息生成成功，ID: {}", player.getId());
            return player.getId();
            
        } catch (Exception e) {
            log.error("生成智能播放器信息失败，用户ID: {}, 结果ID: {}, 错误: {}", 
                     userId, resultId, e.getMessage(), e);
            
            // 创建失败状态记录
            createFailedPlayer(userId, resultId, videoUrl, e.getMessage());
            throw new RuntimeException("生成智能播放器信息失败: " + e.getMessage(), e);
        }
    }

    @Override
    public SmartVideoPlayerDTO getPlayerInfo(Long userId, String resultId) {
        log.info("获取智能播放器信息，用户ID: {}, 结果ID: {}", userId, resultId);

        SmartVideoPlayer player = repository.findByUserIdAndResultId(userId, resultId);
        if (player == null) {
            throw new RuntimeException("未找到播放器信息");
        }

        return convertToDTO(player);
    }

    @Override
    public List<SmartVideoPlayerDTO> getUserPlayerInfos(Long userId) {
        log.info("获取用户的所有播放器信息，用户ID: {}", userId);

        List<SmartVideoPlayer> players = repository.findByUserId(userId);
        return players.stream()
                .map(this::convertToDTO)
                    .collect(Collectors.toList());
    }

    @Override
    @Transactional
    public void updatePlayerStatus(Long userId, String resultId, String status, String errorMessage) {
        log.info("更新播放器状态，用户ID: {}, 结果ID: {}, 状态: {}", userId, resultId, status);

        SmartVideoPlayer player = repository.findByUserIdAndResultId(userId, resultId);
        if (player != null) {
            player.setStatus(status);
            player.setErrorMessage(errorMessage);
            player.setUpdateTime(System.currentTimeMillis());
            repository.updateById(player);
        }
    }

    @Override
    @Transactional
    public void deletePlayerInfo(Long userId, String resultId) {
        log.info("删除播放器信息，用户ID: {}, 结果ID: {}", userId, resultId);

        SmartVideoPlayer player = repository.findByUserIdAndResultId(userId, resultId);
        if (player != null) {
            repository.deleteById(player.getId());
        }
    }

    /**
     * 创建新的播放器信息
     */
    private SmartVideoPlayer createNewPlayer(Long userId, String resultId, String videoUrl,
                                                                          VideoAnalysisResult.VideoAnalysisData analysisData, 
                                           DetailedPostureAnalysis detailedAnalysis) throws Exception {
        SmartVideoPlayer player = new SmartVideoPlayer();
        player.setUserId(userId);
        player.setResultId(resultId);
        player.setVideoUrl(videoUrl);
        player.setStatus("PROCESSING");
        player.setCreateTime(System.currentTimeMillis());
        player.setUpdateTime(System.currentTimeMillis());

        // 设置视频基本信息
        if (analysisData != null && analysisData.getVideoInfo() != null) {
            VideoInfo videoInfo = analysisData.getVideoInfo();
            if (videoInfo.getFps() != null && videoInfo.getFps() > 0) {
                player.setFrameRate(videoInfo.getFps().doubleValue());
                
                if (videoInfo.getTotalFrames() != null) {
                    player.setTotalFrames(videoInfo.getTotalFrames());
                    player.setVideoDuration(videoInfo.getTotalFrames() / videoInfo.getFps().doubleValue());
                } else if (analysisData.getFrames() != null && !analysisData.getFrames().isEmpty()) {
                    // 如果VideoInfo中没有总帧数，从帧数据计算
                    int totalFrames = analysisData.getFrames().size();
                    player.setTotalFrames(totalFrames);
                    player.setVideoDuration(totalFrames / videoInfo.getFps().doubleValue());
                }
            }
        }

        // 生成智能播放器数据
        generatePlayerData(player, analysisData, detailedAnalysis);
        
        player.setStatus("COMPLETED");
        return player;
    }

    /**
     * 更新现有播放器信息
     */
    private void updateExistingPlayer(SmartVideoPlayer player, String videoUrl,
                                    VideoAnalysisResult.VideoAnalysisData analysisData,
                                    DetailedPostureAnalysis detailedAnalysis) throws Exception {
        player.setVideoUrl(videoUrl);
        player.setStatus("PROCESSING");
        player.setUpdateTime(System.currentTimeMillis());

        // 重新生成播放器数据
        generatePlayerData(player, analysisData, detailedAnalysis);
        
        player.setStatus("COMPLETED");
        repository.updateById(player);
    }

    /**
     * 生成播放器智能数据
     */
    private void generatePlayerData(SmartVideoPlayer player, 
                                  VideoAnalysisResult.VideoAnalysisData analysisData,
                                  DetailedPostureAnalysis detailedAnalysis) throws Exception {
        
        log.info("开始生成智能播放器数据，视频时长: {}s", player.getVideoDuration());
        
        // 生成关键时刻
        List<SmartVideoPlayerDTO.KeyMoment> keyMoments = generateKeyMoments(analysisData, detailedAnalysis);
        player.setKeyMoments(objectMapper.writeValueAsString(keyMoments));
        log.debug("生成关键时刻数量: {}", keyMoments.size());

        // 生成慢放片段
        List<SmartVideoPlayerDTO.SlowMotionSegment> slowMotionSegments = generateSlowMotionSegments(analysisData, detailedAnalysis);
        player.setSlowMotionSegments(objectMapper.writeValueAsString(slowMotionSegments));
        log.debug("生成慢放片段数量: {}", slowMotionSegments.size());

        // 生成暂停点
        List<SmartVideoPlayerDTO.PausePoint> pausePoints = generatePausePoints(analysisData, detailedAnalysis);
        player.setPausePoints(objectMapper.writeValueAsString(pausePoints));
        log.debug("生成暂停点数量: {}", pausePoints.size());

        // 生成分析要点
        List<SmartVideoPlayerDTO.AnalysisHighlight> analysisHighlights = generateAnalysisHighlights(analysisData, detailedAnalysis);
        player.setAnalysisHighlights(objectMapper.writeValueAsString(analysisHighlights));
        log.debug("生成分析要点数量: {}", analysisHighlights.size());

        // 生成AI智能播放指令（核心功能）
        List<SmartVideoPlayerDTO.PlaybackInstruction> playbackInstructions = generatePlaybackInstructions(analysisData, detailedAnalysis, player.getVideoDuration());
        player.setPlaybackInstructions(objectMapper.writeValueAsString(playbackInstructions));
        
        // 详细记录AI生成的播放指令
        log.info("🤖 AI智能播放指令生成完成，共 {} 条指令", playbackInstructions.size());
        if (log.isDebugEnabled()) {
            for (int i = 0; i < playbackInstructions.size(); i++) {
                SmartVideoPlayerDTO.PlaybackInstruction inst = playbackInstructions.get(i);
                log.debug("  指令{}: {:.2f}s - {} {} - {}", 
                    i + 1, inst.getTimestamp(), inst.getAction(), 
                    inst.getParameter() != null ? "(" + inst.getParameter() + ")" : "",
                    inst.getMessage());
            }
        }

        // 生成缩略图时间轴
        List<SmartVideoPlayerDTO.ThumbnailTimelineItem> thumbnailTimeline = generateThumbnailTimeline(analysisData);
        player.setThumbnailTimeline(objectMapper.writeValueAsString(thumbnailTimeline));
        log.debug("生成缩略图时间轴数量: {}", thumbnailTimeline.size());

        // 生成交互提示
        List<SmartVideoPlayerDTO.InteractiveTip> interactiveTips = generateInteractiveTips(detailedAnalysis, player.getVideoDuration());
        player.setInteractiveTips(objectMapper.writeValueAsString(interactiveTips));
        log.debug("生成交互提示数量: {}", interactiveTips.size());

        // 生成播放器配置
        SmartVideoPlayerDTO.PlayerConfig playerConfig = generatePlayerConfig();
        player.setPlayerConfig(objectMapper.writeValueAsString(playerConfig));
        
        log.info("智能播放器数据生成完成");
    }

    /**
     * 生成关键时刻 - 基于AI分析结果
     */
    private List<SmartVideoPlayerDTO.KeyMoment> generateKeyMoments(VideoAnalysisResult.VideoAnalysisData analysisData, 
                                                                 DetailedPostureAnalysis detailedAnalysis) {
        List<SmartVideoPlayerDTO.KeyMoment> keyMoments = new ArrayList<>();

        if (detailedAnalysis == null) {
            log.warn("没有详细分析数据，无法生成关键时刻");
            return keyMoments;
        }

        double totalDuration = 0.0;
        
        // 1. 基于运动阶段生成关键时刻
        if (detailedAnalysis.getMovementPhases() != null) {
            double currentTime = 0.0;
            for (int i = 0; i < detailedAnalysis.getMovementPhases().size(); i++) {
                DetailedPostureAnalysis.MovementPhase phase = detailedAnalysis.getMovementPhases().get(i);
                
                SmartVideoPlayerDTO.KeyMoment moment = new SmartVideoPlayerDTO.KeyMoment();
                moment.setTimestamp(currentTime);
                moment.setTitle(phase.getPhaseName() != null ? phase.getPhaseName() : "运动阶段" + (i + 1));
                
                // 根据阶段评分确定重要性
                String importance = "MEDIUM";
                if (phase.getPhaseScore() != null) {
                    if (phase.getPhaseScore() < 70.0) {
                        importance = "HIGH"; // 低分阶段需要重点关注
                        moment.setDescription("评分较低(" + String.format("%.1f", phase.getPhaseScore()) + "分)，需要重点改进");
                    } else if (phase.getPhaseScore() > 90.0) {
                        importance = "LOW"; // 高分阶段表现良好
                        moment.setDescription("表现优秀(" + String.format("%.1f", phase.getPhaseScore()) + "分)，继续保持");
                    } else {
                        moment.setDescription("表现一般(" + String.format("%.1f", phase.getPhaseScore()) + "分)，有改进空间");
                    }
                } else {
                    moment.setDescription("关键动作阶段，注意观察技术要点");
                }
                
                moment.setImportance(importance);
                moment.setCategory("PHASE");
                keyMoments.add(moment);
                
                // 更新时间戳（基于阶段持续时间）
                double phaseDuration = phase.getDuration() != null ? phase.getDuration() : 1.0;
                currentTime += phaseDuration;
                totalDuration = Math.max(totalDuration, currentTime);
            }
        }

        // 如果没有阶段信息，设置默认总时长
        if (totalDuration == 0.0) {
            totalDuration = 10.0; // 默认10秒
        }

        // 2. 基于关节分析生成关键时刻
        if (detailedAnalysis.getJointDetailAnalysis() != null) {
            for (DetailedPostureAnalysis.JointDetailAnalysis joint : detailedAnalysis.getJointDetailAnalysis()) {
                if (joint.getCurrentPerformance() != null && joint.getCurrentPerformance().getRiskFactor() > 8.0) {
                    SmartVideoPlayerDTO.KeyMoment moment = new SmartVideoPlayerDTO.KeyMoment();
                    // 在视频中段位置标记高风险关节
                    moment.setTimestamp(totalDuration * 0.6);
                    moment.setTitle(getJointDisplayName(joint.getJointName()) + "风险提醒");
                    moment.setDescription("风险系数较高(" + String.format("%.1f", joint.getCurrentPerformance().getRiskFactor()) + 
                        ")，需要特别注意");
                    moment.setImportance("HIGH");
                    moment.setCategory("RISK");
                    keyMoments.add(moment);
                }
            }
        }

        // 3. 基于个性化指导生成关键时刻
        if (detailedAnalysis.getPersonalizedCoaching() != null && 
            detailedAnalysis.getPersonalizedCoaching().getImmediateCorrections() != null) {
            for (int i = 0; i < detailedAnalysis.getPersonalizedCoaching().getImmediateCorrections().size() && i < 2; i++) {
                var correction = detailedAnalysis.getPersonalizedCoaching().getImmediateCorrections().get(i);
                
                SmartVideoPlayerDTO.KeyMoment moment = new SmartVideoPlayerDTO.KeyMoment();
                moment.setTimestamp(totalDuration * (0.3 + i * 0.3)); // 分散在视频中
                moment.setTitle("纠正要点: " + correction.getIssue());
                moment.setDescription(correction.getCorrection());
                moment.setImportance("高".equals(correction.getPriority()) || "HIGH".equals(correction.getPriority()) ? "HIGH" : "MEDIUM");
                moment.setCategory("CORRECTION");
                keyMoments.add(moment);
            }
        }

        // 按时间戳排序
        keyMoments.sort((a, b) -> Double.compare(a.getTimestamp(), b.getTimestamp()));
        
        log.debug("基于AI分析生成关键时刻: {}个", keyMoments.size());
        return keyMoments;
    }

    /**
     * 生成慢放片段 - 基于AI分析结果
     */
    private List<SmartVideoPlayerDTO.SlowMotionSegment> generateSlowMotionSegments(VideoAnalysisResult.VideoAnalysisData analysisData, 
                                                                                  DetailedPostureAnalysis detailedAnalysis) {
        List<SmartVideoPlayerDTO.SlowMotionSegment> segments = new ArrayList<>();

        if (detailedAnalysis == null) {
            log.warn("没有详细分析数据，无法生成慢放片段");
            return segments;
        }

        // 获取视频总时长
        double totalDuration = 10.0; // 默认时长
        if (analysisData != null && analysisData.getVideoInfo() != null) {
            VideoInfo videoInfo = analysisData.getVideoInfo();
            if (videoInfo.getTotalFrames() != null && videoInfo.getFps() != null) {
                totalDuration = videoInfo.getTotalFrames() / (double) videoInfo.getFps();
            }
        }

        // 1. 基于关节分析生成慢放片段 - 一致性差的关节需要慢放观察
        if (detailedAnalysis.getJointDetailAnalysis() != null) {
            for (DetailedPostureAnalysis.JointDetailAnalysis joint : detailedAnalysis.getJointDetailAnalysis()) {
                if (joint.getCurrentPerformance() != null) {
                    double consistency = joint.getCurrentPerformance().getConsistency();
                    if (consistency < 70.0) { // 一致性较差
                        SmartVideoPlayerDTO.SlowMotionSegment segment = new SmartVideoPlayerDTO.SlowMotionSegment();
                        segment.setStartTime(totalDuration * 0.4); // 在视频中段
                        segment.setEndTime(totalDuration * 0.4 + 2.0);
                        segment.setSlowRate(0.6); // 根据一致性程度调整速度
                        segment.setReason(getJointDisplayName(joint.getJointName()) + "动作不稳定");
                        segment.setDescription("一致性偏低(" + String.format("%.1f%%", consistency) + 
                            ")，建议慢速观察动作稳定性");
                        segments.add(segment);
                    }
                }
            }
        }

        // 2. 基于生物力学分析生成慢放片段 - 力量输出问题需要慢放
        if (detailedAnalysis.getBiomechanicsAnalysis() != null) {
            var biomechanics = detailedAnalysis.getBiomechanicsAnalysis();
            if (biomechanics.getPowerGeneration() != null) {
                var powerGen = biomechanics.getPowerGeneration();
                if (powerGen.getPowerConsistency() != null && powerGen.getPowerConsistency() < 75.0) {
                    SmartVideoPlayerDTO.SlowMotionSegment segment = new SmartVideoPlayerDTO.SlowMotionSegment();
                    segment.setStartTime(totalDuration * 0.6); // 假设峰值功率在60%时刻
                    segment.setEndTime(totalDuration * 0.6 + 3.0);
                    segment.setSlowRate(0.4); // 超慢速观察力量输出
                    segment.setReason("力量输出分析");
                    segment.setDescription("功率一致性需要改善(" + 
                        String.format("%.1f%%", powerGen.getPowerConsistency()) + ")，慢速观察力量发力过程");
                    segments.add(segment);
                }
            }
        }

        // 3. 基于运动阶段生成慢放片段 - 评分低的阶段需要慢放
        if (detailedAnalysis.getMovementPhases() != null) {
            double currentTime = 0.0;
            for (DetailedPostureAnalysis.MovementPhase phase : detailedAnalysis.getMovementPhases()) {
                if (phase.getPhaseScore() != null && phase.getPhaseScore() < 75.0) {
                    SmartVideoPlayerDTO.SlowMotionSegment segment = new SmartVideoPlayerDTO.SlowMotionSegment();
                    segment.setStartTime(currentTime);
                    double phaseDuration = phase.getDuration() != null ? phase.getDuration() : 2.0;
                    segment.setEndTime(currentTime + Math.min(phaseDuration, 2.5)); // 最多慢放2.5秒
                    segment.setSlowRate(0.5); // 0.5倍速
                    segment.setReason(phase.getPhaseName() + "技术改进");
                    segment.setDescription("阶段评分偏低(" + String.format("%.1f", phase.getPhaseScore()) + 
                        "分)，建议慢速观察技术要点");
                    segments.add(segment);
                }
                currentTime += phase.getDuration() != null ? phase.getDuration() : 1.0;
            }
        }

        // 4. 基于个性化指导生成慢放片段 - 高优先级纠正需要慢放观察
        if (detailedAnalysis.getPersonalizedCoaching() != null && 
            detailedAnalysis.getPersonalizedCoaching().getImmediateCorrections() != null) {
            for (var correction : detailedAnalysis.getPersonalizedCoaching().getImmediateCorrections()) {
                if ("高".equals(correction.getPriority()) || "HIGH".equals(correction.getPriority())) {
                    SmartVideoPlayerDTO.SlowMotionSegment segment = new SmartVideoPlayerDTO.SlowMotionSegment();
                    segment.setStartTime(totalDuration * 0.3); // 在前半段
                    segment.setEndTime(totalDuration * 0.3 + 2.0);
                    segment.setSlowRate(0.5);
                    segment.setReason("重要纠正: " + correction.getIssue());
                    segment.setDescription(correction.getCorrection() + " - 建议慢速观察改进效果");
                    segments.add(segment);
                    break; // 只添加一个高优先级的慢放片段
                }
            }
        }

        log.debug("基于AI分析生成慢放片段: {}个", segments.size());
        return segments;
    }

    /**
     * 生成暂停点 - 基于AI分析结果
     */
    private List<SmartVideoPlayerDTO.PausePoint> generatePausePoints(VideoAnalysisResult.VideoAnalysisData analysisData, 
                                                                    DetailedPostureAnalysis detailedAnalysis) {
        List<SmartVideoPlayerDTO.PausePoint> pausePoints = new ArrayList<>();

        if (detailedAnalysis == null) {
            log.warn("没有详细分析数据，无法生成暂停点");
            return pausePoints;
        }

        // 获取视频总时长
        double totalDuration = 10.0; // 默认时长
        if (analysisData != null && analysisData.getVideoInfo() != null) {
            VideoInfo videoInfo = analysisData.getVideoInfo();
            if (videoInfo.getTotalFrames() != null && videoInfo.getFps() != null) {
                totalDuration = videoInfo.getTotalFrames() / (double) videoInfo.getFps();
            }
        }

        // 1. 基于关节风险生成暂停点 - 高风险关节需要暂停观察
        if (detailedAnalysis.getJointDetailAnalysis() != null) {
            for (DetailedPostureAnalysis.JointDetailAnalysis joint : detailedAnalysis.getJointDetailAnalysis()) {
                if (joint.getCurrentPerformance() != null && joint.getCurrentPerformance().getRiskFactor() > 7.0) {
                    SmartVideoPlayerDTO.PausePoint point = new SmartVideoPlayerDTO.PausePoint();
                    point.setTimestamp(totalDuration * 0.5); // 在视频中段暂停
                    point.setReason(getJointDisplayName(joint.getJointName()) + "风险检查");
                    point.setTip("风险系数较高(" + String.format("%.1f", joint.getCurrentPerformance().getRiskFactor()) + 
                        ")，请仔细观察" + getJointDisplayName(joint.getJointName()) + "的角度和动作");
                    point.setDuration(4); // 风险较高，暂停4秒
                    pausePoints.add(point);
                }
            }
        }

        // 2. 基于运动阶段生成暂停点 - 评分低的阶段需要暂停
        if (detailedAnalysis.getMovementPhases() != null) {
            double currentTime = 0.0;
            for (DetailedPostureAnalysis.MovementPhase phase : detailedAnalysis.getMovementPhases()) {
                if (phase.getPhaseScore() != null && phase.getPhaseScore() < 75.0) {
                    SmartVideoPlayerDTO.PausePoint point = new SmartVideoPlayerDTO.PausePoint();
                    point.setTimestamp(currentTime + (phase.getDuration() != null ? phase.getDuration() * 0.5 : 0.5));
                    point.setReason(phase.getPhaseName() + "技术检查");
                    point.setTip("此阶段评分偏低(" + String.format("%.1f", phase.getPhaseScore()) + 
                        "分)，请观察动作执行是否标准");
                    point.setDuration(3);
                    pausePoints.add(point);
                }
                currentTime += phase.getDuration() != null ? phase.getDuration() : 1.0;
            }
        }

        // 3. 基于生物力学分析生成暂停点 - 平衡稳定性问题需要暂停
        if (detailedAnalysis.getBiomechanicsAnalysis() != null && 
            detailedAnalysis.getBiomechanicsAnalysis().getBalanceStability() != null) {
            var balance = detailedAnalysis.getBiomechanicsAnalysis().getBalanceStability();
            if (balance.getLateralStability() != null && balance.getLateralStability() < 75.0) {
                SmartVideoPlayerDTO.PausePoint point = new SmartVideoPlayerDTO.PausePoint();
                point.setTimestamp(totalDuration * 0.4);
                point.setReason("平衡稳定性检查");
                point.setTip("侧向稳定性偏低(" + String.format("%.1f", balance.getLateralStability()) + 
                    "分)，观察身体重心是否稳定");
                point.setDuration(3);
                pausePoints.add(point);
            }
        }

        // 4. 基于个性化指导生成暂停点 - 高优先级纠正需要暂停强调
        if (detailedAnalysis.getPersonalizedCoaching() != null && 
            detailedAnalysis.getPersonalizedCoaching().getImmediateCorrections() != null) {
            for (int i = 0; i < detailedAnalysis.getPersonalizedCoaching().getImmediateCorrections().size() && i < 2; i++) {
                var correction = detailedAnalysis.getPersonalizedCoaching().getImmediateCorrections().get(i);
                if ("高".equals(correction.getPriority()) || "HIGH".equals(correction.getPriority())) {
                    SmartVideoPlayerDTO.PausePoint point = new SmartVideoPlayerDTO.PausePoint();
                    point.setTimestamp(totalDuration * (0.3 + i * 0.3));
                    point.setReason("重要纠正提醒");
                    point.setTip("发现问题：" + correction.getIssue() + "。建议：" + correction.getCorrection());
                    point.setDuration(4); // 重要纠正，暂停4秒
                    pausePoints.add(point);
                }
            }
        }

        // 按时间戳排序
        pausePoints.sort((a, b) -> Double.compare(a.getTimestamp(), b.getTimestamp()));
        
        log.debug("基于AI分析生成暂停点: {}个", pausePoints.size());
        return pausePoints;
    }

    /**
     * 生成分析要点
     */
    private List<SmartVideoPlayerDTO.AnalysisHighlight> generateAnalysisHighlights(VideoAnalysisResult.VideoAnalysisData analysisData, 
                                                                                   DetailedPostureAnalysis detailedAnalysis) {
        List<SmartVideoPlayerDTO.AnalysisHighlight> highlights = new ArrayList<>();

        // 基于生物力学分析生成要点
        if (detailedAnalysis != null && detailedAnalysis.getBiomechanicsAnalysis() != null) {
            SmartVideoPlayerDTO.AnalysisHighlight highlight = new SmartVideoPlayerDTO.AnalysisHighlight();
            highlight.setTimestamp(5.0);
            highlight.setTitle("生物力学分析");
            highlight.setContent("检测到动作效率分析结果");
            highlight.setType("MOVEMENT");
            highlight.setSeverity("INFO");
            highlight.setSuggestion("注意观察动作的流畅性和协调性");
            highlights.add(highlight);
        }

        return highlights;
    }

    /**
     * 生成播放指令 - 基于AI分析的智能版本
     */
    private List<SmartVideoPlayerDTO.PlaybackInstruction> generatePlaybackInstructions(VideoAnalysisResult.VideoAnalysisData analysisData, 
                                                                                       DetailedPostureAnalysis detailedAnalysis,
                                                                                       Double videoDuration) {
        List<SmartVideoPlayerDTO.PlaybackInstruction> instructions = new ArrayList<>();

        // 使用传入的视频时长，如果为空则设置默认值
        double duration = videoDuration != null ? videoDuration : 10.0;
        System.out.println("🎬 视频时长: " + duration + "s");
        System.out.println("📊 详细分析数据: " + (detailedAnalysis != null ? "存在" : "不存在"));

        // 生成自动播放控制指令
        SmartVideoPlayerDTO.PlaybackInstruction startInstruction = new SmartVideoPlayerDTO.PlaybackInstruction();
        startInstruction.setTimestamp(0.0);
        startInstruction.setAction("PLAY");
        startInstruction.setMessage("开始播放智能分析视频");
        instructions.add(startInstruction);

        if (detailedAnalysis != null) {
            // 1. 基于关节分析生成暂停点 - 检测异常关节角度
            instructions.addAll(generateJointAnalysisInstructions(detailedAnalysis, duration));
            
            // 2. 基于运动阶段生成指令 - 重要阶段需要重点观察
            instructions.addAll(generateMovementPhaseInstructions(detailedAnalysis, duration));
            
            // 3. 基于生物力学分析生成慢放指令 - 力量输出关键时刻
            instructions.addAll(generateBiomechanicsInstructions(detailedAnalysis, duration));
            
            // 4. 基于个性化指导生成提醒指令
            instructions.addAll(generateCoachingInstructions(detailedAnalysis, duration));
        } else {
            System.out.println("❌ 没有详细分析数据，只生成基础播放指令");
        }

        // 按时间戳排序
        instructions.sort((a, b) -> Double.compare(a.getTimestamp(), b.getTimestamp()));
        
        System.out.println("🎮 生成的播放指令数量: " + instructions.size());
        for (int i = 0; i < instructions.size(); i++) {
            SmartVideoPlayerDTO.PlaybackInstruction inst = instructions.get(i);
            System.out.println(String.format("  指令%d: %.2fs - %s %s - %s", 
                i + 1, inst.getTimestamp(), inst.getAction(), 
                inst.getParameter() != null ? "(" + inst.getParameter() + ")" : "",
                inst.getMessage()));
        }

        return instructions;
    }

    /**
     * 基于关节分析生成播放指令
     */
    private List<SmartVideoPlayerDTO.PlaybackInstruction> generateJointAnalysisInstructions(
            DetailedPostureAnalysis detailedAnalysis, double duration) {
        List<SmartVideoPlayerDTO.PlaybackInstruction> instructions = new ArrayList<>();
        
        if (detailedAnalysis.getJointDetailAnalysis() == null) {
            return instructions;
        }
        
        for (DetailedPostureAnalysis.JointDetailAnalysis joint : detailedAnalysis.getJointDetailAnalysis()) {
            if (joint.getCurrentPerformance() == null) continue;
            
            // 如果风险因子较高，在相应时间点添加暂停指令
            double riskFactor = joint.getCurrentPerformance().getRiskFactor();
            if (riskFactor > 5.0) { // 高风险关节
                double timestamp = Math.min(duration * 0.3 + Math.random() * duration * 0.4, duration * 0.8);
                
                SmartVideoPlayerDTO.PlaybackInstruction pauseInstruction = new SmartVideoPlayerDTO.PlaybackInstruction();
                pauseInstruction.setTimestamp(timestamp);
                pauseInstruction.setAction("PAUSE");
                pauseInstruction.setParameter("3"); // 暂停3秒
                pauseInstruction.setMessage("注意观察" + getJointDisplayName(joint.getJointName()) + 
                    "角度 - 风险系数较高(" + String.format("%.1f", riskFactor) + ")");
                instructions.add(pauseInstruction);
                
                // 恢复播放
                SmartVideoPlayerDTO.PlaybackInstruction resumeInstruction = new SmartVideoPlayerDTO.PlaybackInstruction();
                resumeInstruction.setTimestamp(timestamp + 3.0);
                resumeInstruction.setAction("PLAY");
                resumeInstruction.setMessage("继续分析");
                instructions.add(resumeInstruction);
            }
            
            // 如果一致性较差，添加慢放指令
            double consistency = joint.getCurrentPerformance().getConsistency();
            if (consistency < 75.0) { // 一致性较差
                double timestamp = Math.min(duration * 0.4 + Math.random() * duration * 0.3, duration * 0.85);
                
                SmartVideoPlayerDTO.PlaybackInstruction slowInstruction = new SmartVideoPlayerDTO.PlaybackInstruction();
                slowInstruction.setTimestamp(timestamp);
                slowInstruction.setAction("SLOW_MOTION");
                slowInstruction.setParameter("0.6"); // 0.6倍速
                slowInstruction.setMessage("慢速观察" + getJointDisplayName(joint.getJointName()) + 
                    "动作稳定性 - 一致性偏低(" + String.format("%.1f%%", consistency) + ")");
                instructions.add(slowInstruction);
                
                // 恢复正常速度
                SmartVideoPlayerDTO.PlaybackInstruction normalInstruction = new SmartVideoPlayerDTO.PlaybackInstruction();
                normalInstruction.setTimestamp(Math.min(timestamp + 2.0, duration * 0.95));
                normalInstruction.setAction("NORMAL_SPEED");
                normalInstruction.setMessage("恢复正常播放");
                instructions.add(normalInstruction);
            }
        }
        
        return instructions;
    }

    /**
     * 基于运动阶段生成播放指令
     */
    private List<SmartVideoPlayerDTO.PlaybackInstruction> generateMovementPhaseInstructions(
            DetailedPostureAnalysis detailedAnalysis, double duration) {
        List<SmartVideoPlayerDTO.PlaybackInstruction> instructions = new ArrayList<>();
        
        if (detailedAnalysis.getMovementPhases() == null) {
            return instructions;
        }
        
        double currentTime = 0.0;
        for (int i = 0; i < detailedAnalysis.getMovementPhases().size(); i++) {
            DetailedPostureAnalysis.MovementPhase phase = detailedAnalysis.getMovementPhases().get(i);
            
            // 根据阶段持续时间计算实际时间点
            double phaseDuration = phase.getDuration() != null ? phase.getDuration() : duration / detailedAnalysis.getMovementPhases().size();
            double phaseStartTime = currentTime;
            double phaseMidTime = currentTime + phaseDuration * 0.5;
            
            // 如果阶段评分较低，需要重点观察
            if (phase.getPhaseScore() != null && phase.getPhaseScore() < 80.0) {
                SmartVideoPlayerDTO.PlaybackInstruction pauseInstruction = new SmartVideoPlayerDTO.PlaybackInstruction();
                pauseInstruction.setTimestamp(Math.min(phaseMidTime, duration * 0.9));
                pauseInstruction.setAction("PAUSE");
                pauseInstruction.setParameter("2");
                pauseInstruction.setMessage("重点阶段：" + phase.getPhaseName() + 
                    " - 评分偏低(" + String.format("%.1f", phase.getPhaseScore()) + "分)");
                instructions.add(pauseInstruction);
                
                SmartVideoPlayerDTO.PlaybackInstruction resumeInstruction = new SmartVideoPlayerDTO.PlaybackInstruction();
                resumeInstruction.setTimestamp(Math.min(phaseMidTime + 2.0, duration * 0.95));
                resumeInstruction.setAction("PLAY");
                resumeInstruction.setMessage("继续观察");
                instructions.add(resumeInstruction);
            }
            
            currentTime += phaseDuration;
            if (currentTime >= duration * 0.9) break; // 避免超出视频时长
        }
        
        return instructions;
    }

    /**
     * 基于生物力学分析生成播放指令
     */
    private List<SmartVideoPlayerDTO.PlaybackInstruction> generateBiomechanicsInstructions(
            DetailedPostureAnalysis detailedAnalysis, double duration) {
        List<SmartVideoPlayerDTO.PlaybackInstruction> instructions = new ArrayList<>();
        
        if (detailedAnalysis.getBiomechanicsAnalysis() == null) {
            return instructions;
        }
        
        var biomechanics = detailedAnalysis.getBiomechanicsAnalysis();
        
        // 如果力量生成有问题，在峰值功率时刻慢放
        if (biomechanics.getPowerGeneration() != null) {
            var powerGen = biomechanics.getPowerGeneration();
            if (powerGen.getPowerConsistency() != null && powerGen.getPowerConsistency() < 80.0) {
                double timestamp = duration * 0.6; // 假设峰值功率在60%时刻
                
                SmartVideoPlayerDTO.PlaybackInstruction slowInstruction = new SmartVideoPlayerDTO.PlaybackInstruction();
                slowInstruction.setTimestamp(Math.min(timestamp, duration * 0.8));
                slowInstruction.setAction("SLOW_MOTION");
                slowInstruction.setParameter("0.4"); // 0.4倍速，更慢
                slowInstruction.setMessage("力量输出分析 - 功率一致性需要改善(" + 
                    String.format("%.1f%%", powerGen.getPowerConsistency()) + ")");
                instructions.add(slowInstruction);
                
                SmartVideoPlayerDTO.PlaybackInstruction normalInstruction = new SmartVideoPlayerDTO.PlaybackInstruction();
                normalInstruction.setTimestamp(Math.min(timestamp + 2.5, duration * 0.9));
                normalInstruction.setAction("NORMAL_SPEED");
                normalInstruction.setMessage("力量分析完成");
                instructions.add(normalInstruction);
            }
        }
        
        // 如果平衡稳定性有问题，在相关时刻暂停
        if (biomechanics.getBalanceStability() != null) {
            var balance = biomechanics.getBalanceStability();
            if (balance.getLateralStability() != null && balance.getLateralStability() < 80.0) {
                double timestamp = duration * 0.4;
                
                SmartVideoPlayerDTO.PlaybackInstruction pauseInstruction = new SmartVideoPlayerDTO.PlaybackInstruction();
                pauseInstruction.setTimestamp(Math.min(timestamp, duration * 0.8));
                pauseInstruction.setAction("PAUSE");
                pauseInstruction.setParameter("3");
                pauseInstruction.setMessage("平衡稳定性检查 - 侧向稳定性偏低(" + 
                    String.format("%.1f", balance.getLateralStability()) + "分)");
                instructions.add(pauseInstruction);
                
                SmartVideoPlayerDTO.PlaybackInstruction resumeInstruction = new SmartVideoPlayerDTO.PlaybackInstruction();
                resumeInstruction.setTimestamp(Math.min(timestamp + 3.0, duration * 0.9));
                resumeInstruction.setAction("PLAY");
                resumeInstruction.setMessage("继续平衡分析");
                instructions.add(resumeInstruction);
            }
        }
        
        return instructions;
    }

    /**
     * 基于个性化指导生成播放指令
     */
    private List<SmartVideoPlayerDTO.PlaybackInstruction> generateCoachingInstructions(
            DetailedPostureAnalysis detailedAnalysis, double duration) {
        List<SmartVideoPlayerDTO.PlaybackInstruction> instructions = new ArrayList<>();
        
        if (detailedAnalysis.getPersonalizedCoaching() == null) {
            return instructions;
        }
        
        var coaching = detailedAnalysis.getPersonalizedCoaching();
        
        // 基于立即纠正建议生成指令
        if (coaching.getImmediateCorrections() != null) {
            for (int i = 0; i < coaching.getImmediateCorrections().size() && i < 3; i++) {
                var correction = coaching.getImmediateCorrections().get(i);
                
                // 高优先级的纠正需要暂停强调
                if ("高".equals(correction.getPriority()) || "HIGH".equals(correction.getPriority())) {
                    double timestamp = duration * (0.3 + i * 0.2); // 分散在视频中
                    
                    SmartVideoPlayerDTO.PlaybackInstruction pauseInstruction = new SmartVideoPlayerDTO.PlaybackInstruction();
                    pauseInstruction.setTimestamp(Math.min(timestamp, duration * 0.8));
                    pauseInstruction.setAction("PAUSE");
                    pauseInstruction.setParameter("3");
                    pauseInstruction.setMessage("重要纠正：" + correction.getIssue() + " - " + correction.getCorrection());
                    instructions.add(pauseInstruction);
                    
                    SmartVideoPlayerDTO.PlaybackInstruction resumeInstruction = new SmartVideoPlayerDTO.PlaybackInstruction();
                    resumeInstruction.setTimestamp(Math.min(timestamp + 3.0, duration * 0.9));
                    resumeInstruction.setAction("PLAY");
                    resumeInstruction.setMessage("继续观察改进效果");
                    instructions.add(resumeInstruction);
                }
            }
        }
        
        return instructions;
    }

    /**
     * 获取关节显示名称
     */
    private String getJointDisplayName(String jointName) {
        if (jointName == null) return "未知关节";
        
        switch (jointName.toLowerCase()) {
            case "rightknee": return "右膝";
            case "leftknee": return "左膝";
            case "rightelbow": return "右肘";
            case "leftelbow": return "左肘";
            case "trunk": return "躯干";
            case "rightankle": return "右踝";
            case "leftankle": return "左踝";
            case "rightshoulder": return "右肩";
            case "leftshoulder": return "左肩";
            default: return jointName;
        }
    }

    /**
     * 生成缩略图时间轴
     */
    private List<SmartVideoPlayerDTO.ThumbnailTimelineItem> generateThumbnailTimeline(VideoAnalysisResult.VideoAnalysisData analysisData) {
        List<SmartVideoPlayerDTO.ThumbnailTimelineItem> timeline = new ArrayList<>();

        // 基于视频信息生成缩略图时间轴
        if (analysisData != null && analysisData.getVideoInfo() != null) {
            VideoInfo videoInfo = analysisData.getVideoInfo();
            if (videoInfo.getTotalFrames() != null && videoInfo.getFps() != null) {
                int totalFrames = videoInfo.getTotalFrames();
                int fps = videoInfo.getFps();
                
                // 每5秒生成一个缩略图点
                for (int i = 0; i < totalFrames; i += fps * 5) {
                    SmartVideoPlayerDTO.ThumbnailTimelineItem item = new SmartVideoPlayerDTO.ThumbnailTimelineItem();
                    item.setTimestamp(i / (double) fps);
                    item.setThumbnailUrl("/api/video/thumbnail/" + i); // 示例URL
                    item.setDescription("第" + (i / fps) + "秒");
                    item.setIsKeyFrame(i % (fps * 10) == 0); // 每10秒标记为关键帧
                    timeline.add(item);
                }
            }
        }

        return timeline;
    }

    /**
     * 生成交互提示
     */
    private List<SmartVideoPlayerDTO.InteractiveTip> generateInteractiveTips(DetailedPostureAnalysis detailedAnalysis, Double videoDuration) {
        List<SmartVideoPlayerDTO.InteractiveTip> tips = new ArrayList<>();

        // 生成基础的交互提示 - 显示时长2秒
        SmartVideoPlayerDTO.InteractiveTip welcomeTip = new SmartVideoPlayerDTO.InteractiveTip();
        welcomeTip.setTimestamp(1.0);
        welcomeTip.setType("OVERLAY");
        welcomeTip.setPosition("TOP");
        welcomeTip.setContent("AI智能分析开始，注意观察关键动作");
        welcomeTip.setDisplayDuration(2000); // 2秒显示
        welcomeTip.setStyle("info");
        tips.add(welcomeTip);

        // 如果有详细分析，为每个运动阶段添加提示
        if (detailedAnalysis != null && detailedAnalysis.getMovementPhases() != null) {
            for (int i = 0; i < detailedAnalysis.getMovementPhases().size() && i < 4; i++) {
                DetailedPostureAnalysis.MovementPhase phase = detailedAnalysis.getMovementPhases().get(i);
                
                SmartVideoPlayerDTO.InteractiveTip phaseTip = new SmartVideoPlayerDTO.InteractiveTip();
                // 基于实际视频时长分布关键时刻，避免超出视频总时长
                double duration = videoDuration != null ? videoDuration : 10.0;
                double timestamp = Math.min((i + 1) * (duration / 5.0), duration * 0.8); // 在视频前80%时间内均匀分布
                phaseTip.setTimestamp(timestamp);
                phaseTip.setType("OVERLAY");
                phaseTip.setPosition("BOTTOM");
                phaseTip.setContent("关键阶段：" + (phase.getPhaseName() != null ? phase.getPhaseName() : "动作阶段" + (i + 1)) + 
                                  " - 注意观察技术要点");
                phaseTip.setDisplayDuration(2000); // 2秒显示
                phaseTip.setStyle("highlight");
                tips.add(phaseTip);
            }
        }

        return tips;
    }

    /**
     * 生成播放器配置
     */
    private SmartVideoPlayerDTO.PlayerConfig generatePlayerConfig() {
        SmartVideoPlayerDTO.PlayerConfig config = new SmartVideoPlayerDTO.PlayerConfig();
        config.setAutoPlay(false);
        config.setShowControls(true);
        config.setEnableKeyboardShortcuts(true);
        config.setDefaultPlaybackRate(1.0);
        config.setEnableProgressPreview(true);
        config.setShowAnalysisOverlay(true);
        config.setTheme("LIGHT");
        config.setEnabledFeatures(List.of("SLOW_MOTION", "PAUSE_POINTS", "ANALYSIS_OVERLAY", "THUMBNAILS"));
        return config;
    }

    /**
     * 创建失败状态的播放器记录
     */
    private void createFailedPlayer(Long userId, String resultId, String videoUrl, String errorMessage) {
        try {
            SmartVideoPlayer player = new SmartVideoPlayer();
            player.setUserId(userId);
            player.setResultId(resultId);
            player.setVideoUrl(videoUrl);
            player.setStatus("FAILED");
            player.setErrorMessage(errorMessage);
            player.setCreateTime(System.currentTimeMillis());
            player.setUpdateTime(System.currentTimeMillis());
            repository.insert(player);
        } catch (Exception e) {
            log.error("创建失败状态播放器记录也失败: {}", e.getMessage(), e);
        }
    }

    /**
     * 转换为DTO
     */
    private SmartVideoPlayerDTO convertToDTO(SmartVideoPlayer entity) {
        SmartVideoPlayerDTO dto = new SmartVideoPlayerDTO();
        BeanUtils.copyProperties(entity, dto);

        // 转换时间字段
        if (entity.getCreateTime() != null) {
            dto.setCreateTime(java.time.LocalDateTime.ofInstant(
                java.time.Instant.ofEpochMilli(entity.getCreateTime()), 
                java.time.ZoneId.systemDefault()));
        }
        
        if (entity.getUpdateTime() != null) {
            dto.setUpdateTime(java.time.LocalDateTime.ofInstant(
                java.time.Instant.ofEpochMilli(entity.getUpdateTime()), 
                java.time.ZoneId.systemDefault()));
        }

        // 解析JSON字段
        try {
            if (entity.getKeyMoments() != null) {
                dto.setKeyMoments(objectMapper.readValue(entity.getKeyMoments(), 
                    new TypeReference<List<SmartVideoPlayerDTO.KeyMoment>>() {}));
            }
            if (entity.getSlowMotionSegments() != null) {
                dto.setSlowMotionSegments(objectMapper.readValue(entity.getSlowMotionSegments(), 
                    new TypeReference<List<SmartVideoPlayerDTO.SlowMotionSegment>>() {}));
            }
            if (entity.getPausePoints() != null) {
                dto.setPausePoints(objectMapper.readValue(entity.getPausePoints(), 
                    new TypeReference<List<SmartVideoPlayerDTO.PausePoint>>() {}));
            }
            if (entity.getAnalysisHighlights() != null) {
                dto.setAnalysisHighlights(objectMapper.readValue(entity.getAnalysisHighlights(), 
                    new TypeReference<List<SmartVideoPlayerDTO.AnalysisHighlight>>() {}));
            }
            if (entity.getPlaybackInstructions() != null) {
                dto.setPlaybackInstructions(objectMapper.readValue(entity.getPlaybackInstructions(), 
                    new TypeReference<List<SmartVideoPlayerDTO.PlaybackInstruction>>() {}));
            }
            if (entity.getThumbnailTimeline() != null) {
                dto.setThumbnailTimeline(objectMapper.readValue(entity.getThumbnailTimeline(), 
                    new TypeReference<List<SmartVideoPlayerDTO.ThumbnailTimelineItem>>() {}));
            }
            if (entity.getInteractiveTips() != null) {
                dto.setInteractiveTips(objectMapper.readValue(entity.getInteractiveTips(), 
                    new TypeReference<List<SmartVideoPlayerDTO.InteractiveTip>>() {}));
            }
            if (entity.getPlayerConfig() != null) {
                dto.setPlayerConfig(objectMapper.readValue(entity.getPlayerConfig(), 
                    SmartVideoPlayerDTO.PlayerConfig.class));
            }
        } catch (Exception e) {
            log.warn("解析播放器JSON数据失败: {}", e.getMessage());
        }

        return dto;
    }
} 